!> 3D nearest neighbor particle search (normal distribution)
program main

    use random_module, only: randn, randu
    use nnps_module, only: wp, nnps_direct3d, nnps_octree, nnps_grid3d
    use nnpx_command_line, only: get_m_value_from_CLI
    use timer_module, only: timer, sec2hms
    use display_module, only: display
    implicit none
    real(wp), dimension(:, :), allocatable :: loc
    integer :: loop, i
    integer :: m
    real :: loading_factor
    type(timer) :: tmr
    type(nnps_direct3d) :: nnps_direct
    type(nnps_octree) :: nnps_tree
    type(nnps_grid3d) :: nnps_grid
    integer, pointer :: pairs(:)
    real(wp), pointer :: rdxs(:)
    real(wp) :: t1, t2

    call get_m_value_from_CLI(m, loading_factor)
    loop = 1000
    allocate (loc(3, m))
    call randn(loc, 0.0_wp, 5.0_wp)
    call nnps_direct%init(loc, m)
    call nnps_tree%init(loc, minval(loc, 2), maxval(loc, 2))
    call nnps_grid%init(loc, m)

    call cpu_time(t1)
    call tmr%tic()
    do i = 1, loop
        call nnps_grid%query(1.0_wp, pairs, rdxs, m)
    end do

    print *, "*** grid3d ***"
    call display(sec2hms(tmr%toc()), 'time:', inline=.true.)
    call cpu_time(t2)
    call display(t2 - t1, 'cpu_time:', inline=.true.)
    call display(pairs, 'pairs:')

    call cpu_time(t1)
    call tmr%tic()
    do i = 1, loop
        call nnps_tree%build(m)
        call nnps_tree%query(1.0_wp, pairs, rdxs, m)
    end do

    print *, "*** tree3d ***"
    call display(sec2hms(tmr%toc()), 'time:', inline=.true.)
    call cpu_time(t2)
    call display(t2 - t1, 'cpu_time:', inline=.true.)
    call display(pairs, 'pairs:')

    call cpu_time(t1)
    call tmr%tic()
    do i = 1, loop
        call nnps_direct%query(1.0_wp, pairs, rdxs, m)
    end do

    print *, "*** direct3d ***"
    call display(sec2hms(tmr%toc()), 'time:', inline=.true.)
    call cpu_time(t2)
    call display(t2 - t1, 'cpu_time:', inline=.true.)
    call display(pairs, 'pairs:')

end program main
!>  grid3d: 00:00:00.510
!> [vector: 2466] pairs:
!>  1.790E+02,  2.600E+02,  1.790E+02, ...  9.530E+02
!>  tree3d: 00:00:47.428
!> [vector: 2466] pairs:
!>  2.000E+00,  3.600E+01,  2.000E+00, ...  9.830E+02
!>  direct3d: 00:00:03.357
!> [vector: 2466] pairs:
!>  2.000E+00,  3.600E+01,  2.000E+00, ...  9.830E+02
